package com.hong.pdf2img.utils;



import com.hong.pdf2img.MainApplication;
import com.sun.scenario.effect.ImageData;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.io.RandomAccessReadBufferedFile;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.text.PDFTextStripper;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

/**
 * @Description: pdf转图片工具类
 * @Version: 1.0
 */
public class PdfToImageUtil {

    public static List<BufferedImage> pdfToImageForAllPage(String fileName) throws Exception {
        try (PDDocument document = Loader.loadPDF(new RandomAccessReadBufferedFile(fileName))) {
            return getImageAction(document, null, MainApplication.img_quality);
        }
    }

    public static List<BufferedImage> pdfToImageForMultiPage(String fileName,List<Integer> pageList) throws Exception {
        try (PDDocument document = Loader.loadPDF(new RandomAccessReadBufferedFile(fileName))) {
            return getImageAction(document, pageList, MainApplication.img_quality);
        }
    }

    /**
     * 获取PDF页面图像（高效版本）
     */
    public static List<BufferedImage> getImageAction(PDDocument pdfDocument, List<Integer> pageList, int dpi) throws IOException {
        List<BufferedImage> images = new ArrayList<>();
        PDFRenderer renderer = new PDFRenderer(pdfDocument);
        Set<Integer> targetPages = (pageList != null) ? new HashSet<>(pageList) : null;
        for (int i = 0; i < pdfDocument.getNumberOfPages(); i++) {
            if (targetPages != null && !targetPages.contains(i + 1)) continue;
            BufferedImage image = renderer.renderImageWithDPI(i, dpi);    // 直接渲染为BufferedImage，避免任何转换
            images.add(image);
        }
        return images;
    }

    public static Boolean saveImage(byte[] imageBytes, String savePath,String fileName) throws Exception {
            BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
            return saveImage(image, savePath, fileName);
    }

    public static Boolean saveImage(BufferedImage image, String savePath,String fileName) throws Exception {
        try {
            File directory = new File(savePath);
            if(!directory.exists()){
                directory.mkdirs();
            }
            File file1 = new File(directory,fileName);
            return ImageIO.write(image, MainApplication.img_format_value, file1);
        } catch (IOException e) {
            AppLogger.error("保存图片失败", e);
//            e.printStackTrace();
            return false;
        }
    }


    /**
     * 拼接长图
     * @param imgBytesList
     * @return
     */
    public static BufferedImage mergeLongImage(List<BufferedImage> imgBytesList) throws IOException {
        int totalHeight = 0;
        int maxWidth = 0;
        List<BufferedImage> bufferedImageList = new ArrayList<>();
        // 加载所有图片并计算尺寸
        for (BufferedImage bufferedImage : imgBytesList) {
            if (bufferedImage == null) continue; // 跳过无效图片
            totalHeight += bufferedImage.getHeight();
            maxWidth = Math.max(maxWidth, bufferedImage.getWidth());
            bufferedImageList.add(bufferedImage);
        }
        if (bufferedImageList.isEmpty()) throw new IOException("没有有效的图片数据");
        BufferedImage destImage = new BufferedImage(maxWidth, totalHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = destImage.createGraphics();// 使用Graphics2D绘制（更安全）
        try {
            g2d.fillRect(0, 0, maxWidth, totalHeight);
            int currentY = 0;
            for (BufferedImage img : bufferedImageList) {
                int imgW = img.getWidth();
                int imgH = img.getHeight();
                int startX = (maxWidth - imgW) / 2; // 居中放置
                g2d.drawImage(img, startX, currentY, null); // 绘制图片（自动处理边界）
                currentY += imgH;
            }
        } finally {
            g2d.dispose();
        }
        return destImage;
    }

    /**
     * 提取嵌入的图片资源
     * @param fileName
     * @param pageList
     * @return
     * @throws IOException
     */
    public static List<BufferedImage> extractEmbeddedImages(String fileName,List<Integer> pageList) throws IOException {
        try (PDDocument document = Loader.loadPDF(new RandomAccessReadBufferedFile(fileName))) {
            return extractEmbeddedImages(document, pageList);
        }
    }
    /**
     * 提取嵌入的图片资源
     */
    public static List<BufferedImage> extractEmbeddedImages(PDDocument document,List<Integer> pageList) throws IOException {
        List<BufferedImage> images = new ArrayList<>();
        Set<Integer> targetPages = (pageList != null) ? new HashSet<>(pageList) : null;
        for (int i = 0; i < document.getNumberOfPages(); i++) {
            if (targetPages != null && !targetPages.contains(i + 1)) continue;
            PDPage page = document.getPage(i);
            PDResources resources = page.getResources();
            if (resources == null) continue;
            for (COSName name : resources.getXObjectNames()) {
                if (resources.isImageXObject(name)) {
                    PDImageXObject image = (PDImageXObject) resources.getXObject(name);
                    images.add(image.getImage());
                }
            }
        }
        return images;
    }

    public static String getStrings(String fileName,List<Integer> pageList) throws IOException {
        try (PDDocument document = Loader.loadPDF(new RandomAccessReadBufferedFile(fileName))) {
            PDFTextStripper stripper = new PDFTextStripper();   //文本剥离器
            stripper.setSortByPosition(true);   //按位置进行排序
            String text=null;
            if(pageList != null && !pageList.isEmpty()){
                StringBuilder stringBuilder=new StringBuilder();
                for(Integer page:pageList){
                    stripper.setStartPage(page);
                    stripper.setEndPage(page);
                    stringBuilder.append(stripper.getText(document));
                }
                text=stringBuilder.toString();
            }else
                text= stripper.getText(document);   //获取文本
            document.close();   //关闭文档对象
            return text;
        }
    }
}

